﻿using BaseFramework;
using LiteFramework.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;
using System.Security.Permissions;
using System.Security.Principal;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;

namespace LiteFramework.Server
{
    [Serializable]
    public sealed class AccessPermission : IPermission, IUnrestrictedPermission
    {
        private bool _unrestricted = true;
        private string _taskCodes = null;

        public AccessPermission(bool unrestricted, string taskCodes)
        {
            this._unrestricted = unrestricted;
            this._taskCodes = taskCodes;
        }

        public AccessPermission(PermissionState state)
        {
            _unrestricted = (state == PermissionState.Unrestricted);
        }

        #region IPermission Members

        public IPermission Copy()
        {
            return new AccessPermission(this._unrestricted, this._taskCodes);
        }

        public void Demand()
        {
            var context = ServiceSecurityContext.Current;

            var principal = System.Threading.Thread.CurrentPrincipal;
            var id = WindowsIdentity.GetCurrent();

            User user = ServerApplication.User;

            if (ServerApplication.IsGlobleAdmin(user))
                return;

            if (user == null || user.Identity == null || !user.Identity.IsAuthenticated)
                throw new AccessSecurityException("因为未执行登录或者身份未验证，用户访问已被拒绝。");

            if (!user.IsApprole && !user.IsOnline)
                throw new AccessSecurityException("因为会话超时而离线，用户 (" + (!string.IsNullOrEmpty(user.NickName) ? user.NickName : (!string.IsNullOrEmpty(user.RealName) ? user.RealName : user.UserName)) + ") 访问已被拒绝。");

            if (!user.IsApprole && !String.IsNullOrEmpty(_taskCodes))
            {
                string[] taskCodes = _taskCodes.Split(new char[] { System.IO.Path.PathSeparator });
                if (user.HasTask(taskCodes))
                    return;

                string message = null;
                if (taskCodes.Length == 1)
                {
                    string desc = taskCodes[0];
                    if (desc == SystemResources.TASK_CODE_NOT_SUPPLIED)
                    {
                        desc = "系统未提供此功能";
                    }
                    else
                    {
                        try
                        {
                            //IPermissionContract server = ServerApplication.ComponentFactory.Create<IPermissionContract>();
                            //desc = server.GetTaskDescription(taskCodes[0]);
                        }
                        catch { }

                        message = "用户【" + (!string.IsNullOrEmpty(user.NickName) ? user.NickName : (!string.IsNullOrEmpty(user.RealName) ? user.RealName : user.UserName)) + "】无【" + (!string.IsNullOrEmpty(desc) ? desc : taskCodes[0]) + "】权限。";
                    }
                }
                else
                {
                    message = "用户【" + (!string.IsNullOrEmpty(user.NickName) ? user.NickName : (!string.IsNullOrEmpty(user.RealName) ? user.RealName : user.UserName)) + "】无此操作权限。";
                }

                throw new AccessSecurityException(message);
            }
        }

        public bool IsSubsetOf(IPermission target)
        {
            return false;
        }

        public IPermission Intersect(IPermission target)
        {
            return null;
        }

        public IPermission Union(IPermission target)
        {
            return null;
        }

        #endregion

        #region ISecurityEncodable Members

        public void FromXml(SecurityElement elem)
        {
            if (elem == null)
                throw new ArgumentNullException("elem");

            string flag = elem.Attribute("Unrestricted");
            if (flag != null)
                this._unrestricted = bool.Parse(flag);

            flag = elem.Attribute("TaskCodes");
            if (flag != null)
                _taskCodes = flag;
        }

        public SecurityElement ToXml()
        {
            SecurityElement elem = new SecurityElement("IPermission");

            elem.AddAttribute("class", this.GetType().AssemblyQualifiedName);
            elem.AddAttribute("version", "1");

            elem.AddAttribute("Unrestricted", this._unrestricted.ToString());
            if (_taskCodes != null)
                elem.AddAttribute("TaskCodes", _taskCodes);

            return elem;
        }

        #endregion

        #region IUnrestrictedPermission Members

        public bool IsUnrestricted()
        {
            return this._unrestricted;
        }

        #endregion
    }
}
